#ifndef AST_DECLARATIONVARIABLE
#define AST_DECLARATIONVARIABLE
#include <string>
#include "node.h"

namespace AST {

    /**
     * Declaração de Variável
     *
     * Estrutura utilizada para armazenamento de declarações de variáveis
     * utilizadas no programa de entrada do compilador. Estas declarações
     * necessitam de informações como tipo de dado relacionado e identificador
     * utilizado.
     *
     * @category AST
     * @package  AST
     */
    class DeclarationVariable : public Node {

    private:

        /**
         * Identificador da Variável
         */
        std::string* _identifier;

        /**
         * Tipo de Dado Definido
         */
        Node* _type;

        /**
         * Configura o Identificador da Variável
         *
         * Método utilizado para configurar o identificador utilizado pela
         * variável no momento de sua criação. Este identificador deve ser único
         * no escopo que está sendo definido.
         *
         * @param  std::string* Conteúdo Identificador para Configuração
         * @return DeclarationVariable* Próprio Objeto para Encadeamento
         */
        DeclarationVariable* _setIdentifier(std::string*);

    public:

        /**
         * Construtor
         *
         * Criação de variável no escopo de execução, informando seu
         * identificador, que deve ser único naquele espaço de execução. Sua
         * tipagem deve ser configurada após sua criação, devido às produções
         * descritas.
         *
         * @param std::string* Conteúdo Identificador para Configuração
         */
        DeclarationVariable(std::string*);

        /**
         * Construtor Especializado
         *
         * Criação de variável no escopo de execução com tipagem de dado
         * definida no momento da leitura, como nas definições de função. Porém,
         * existem casos que a tipagem somente é definida depois da leitura
         * completa de todas as definições em formato de lista, como nas
         * declarações de variáveis em início de bloco.
         *
         * @param  std::string* Conteúdo Identificador para Configuração
         * @param  Node*        Tipo de Dado Apresentado
         */
        DeclarationVariable(std::string*, Node*);

        /**
         * Apresenta o Identificador da Variável
         *
         * O identificador da variável é o conteúdo que deve ser apresentado
         * durante a construção da instância desta classe. Este identificador
         * deve ser único no escopo atual da variável.
         *
         * @return std::string* Conteúdo Configurado
         */
        std::string* getIdentifier();

        /**
         * Configuração do Tipo de Dado
         *
         * A variável deve estar tipada no momento de sua criação, porém
         * conforme produção da gramática que gera a declaração de variáveis,
         * não temos o tipo definido quando seu identificador é capturado por
         * causa da possibilidade de listagem. Portanto, o tipo sempre será
         * configurado após a definição dos identificadores daquele tipo.
         *
         * @param  Node* Tipo Definido para a Variável
         * @return DeclarationVariable Próprio Objeto para Encadeamento
         */
        DeclarationVariable* setType(Node*);

        /**
         * Apresenta o Tipo de Dado Definido
         *
         * Cada variável deve receber um tipo de dado definido para alocação de
         * espaço em memória. Este tipo de dado é configurado após a leitura da
         * definição de todos os identificadores adicionados.
         *
         * @return Node* Tipo de Dado Configurado
         */
        Node* getType();

        // Sobrescrita
        std::string toString(int);

    };

};

#endif

